home *** CD-ROM | disk | FTP | other *** search
- ; -*- Mode: Lisp; Syntax: Common-Lisp; Package: SCHEME-HACKS; -*-
- ; File hacks.lisp / Copyright (c) 1991 Jonathan Rees / See file COPYING
-
- ; Things that both the translator and the runtime system need. For
- ; level-crossing to work (i.e. EVAL), these things must be shared
- ; between the two; for bootstrapping an incompatible system they must
- ; not be shared.
-
- ; ----- Cope with vagaries of #+ in VAX LISP
-
- (lisp:in-package "SCHEME-HACKS" :use '("LISP"))
-
- (export '(
- ;; Things used by the translator and by the runtime system
- intern-renaming-perhaps ;code generator
- qualified-symbol-p
- make-photon
- photon-p ;rep loop
-
- ;; Things used by runtime system
- find-symbol-renaming-perhaps
- lisp-package
- scheme-package
- scheme-readtable
- *non-scheme-readtable*
- fix-scheme-package-if-necessary
- clever-load
- ))
-
- (eval-when (eval load compile)
- (when (find-if #'(lambda (feature)
- (and (symbolp feature)
- (string= (symbol-name feature) "DEC")))
- *features*)
- (pushnew ':DEC *features*)))
-
- ; ----- Photons
-
- ; "A ``photon'' is an object that PRIN1's as if it had been PRINC'ed."
- ; -- KMP
- ;
- ; Photons are used by the runtime system to make the unspecified and
- ; unassigned objects and to produce values to be returned by DEFINE
- ; forms. Photons are used by the translator to generate code that has
- ; #+, #-, and #. forms in it.
-
- (defstruct (photon (:constructor make-photon (string-or-function))
- (:copier nil)
- (:print-function print-photon))
- string-or-function)
-
- (defun print-photon (photon stream escape?)
- (declare (ignore escape?))
- (let ((z (photon-string-or-function photon)))
- (if (stringp z)
- (princ z stream)
- (funcall z stream))))
-
- ; ----- The SCHEME package:
-
- ; It's important that scheme symbols print as SCHEME::FOO when the
- ; Scheme package is not current.
-
- (defvar scheme-package)
-
- (defun qualified-symbol-p (sym)
- (and (symbolp sym)
- (not (eq (symbol-package sym) scheme-package))))
-
- (defun pollutedp (package)
- (do-symbols (sym package)
- (when (qualified-symbol-p sym) (return-from pollutedp t))))
-
- (defun fix-scheme-package-if-necessary (package)
- (setq scheme-package package)
- (if (not (equal (package-name package) "SCHEME"))
- (rename-package package "SCHEME"))
- (cond ((pollutedp package)
- (purify-scheme-package package))))
-
- ; Things about whose EQ-ness we care:
-
- (defparameter losers
- '("DEFINE"
- "ELSE" "=>" "UNQUOTE" "UNQUOTE-SPLICING"
- "HEUR" "B" "O" "D" "X"))
-
- (defun purify-scheme-package (package)
- (format t "~&Purifying...")
- (let ((*package* package)) ;help circumvent slime bugs
- (let ((lisp-package (find-package "LISP"))
- (winners (mapcar #'(lambda (name)
- (intern name package))
- losers)))
- (unuse-package (package-use-list package) package)
- (import winners package)
- (do-symbols (sym package)
- (cond ((eq (symbol-package sym) package)
- (unexport sym package)
- ;; OK, do nothing.
- )
- ((eq sym (find-symbol (symbol-name sym) lisp-package))
- (let ((name (symbol-name sym)))
- (if (member name losers :test #'string=)
- (error "~S shouldn't be accessible in the LISP package, but it is."
- sym))
- (unintern sym package)
- (let ((new-sym (intern name package)))
- (assert (eq (symbol-package new-sym) package)
- () "Lost on ~S" new-sym)
- (symbol-forward sym new-sym))))
- (t
- (purify-symbol sym package)))))))
-
- ; Clobber the symbol's home package so that it prints
- ; as SCHEME::FOO.
- (defun purify-symbol (sym package)
- (unexport sym package)
- (let ((name (symbol-name sym))
- (old-package (symbol-package sym)))
- (format t " ~S" sym)
- (unexport sym old-package)
- (unintern sym old-package) ;?
- (import sym package)
- #+Lispm ;?
- (setf (symbol-package sym) package)
- (multiple-value-bind (hucairz status)
- (find-symbol name old-package)
- (declare (ignore hucairz))
- (unless status ;inherited
- (import sym old-package)))
- (unless (and (eq sym (find-symbol name package))
- (eq (symbol-package sym) package))
- (format t "~& (Failed to move ~S to ~A package)~%"
- sym
- (package-name package)))))
-
- (defun symbol-forward (from-sym to-sym)
- (when (boundp from-sym)
- (setf (symbol-value to-sym) (symbol-value from-sym))
- (proclaim `(special ,to-sym)))
- (cond ((or (special-form-p from-sym)
- (macro-function from-sym))
- (setf (macro-function to-sym)
- #'(lambda (form env)
- (declare (ignore env))
- (cons from-sym (cdr form)))))
- ((fboundp from-sym)
- (setf (symbol-function to-sym)
- (symbol-function from-sym)))))
-
- ; ----- The LISP package:
-
- (defparameter lisp-package
- (find-package #-:DEC "LISP" #+:DEC "COMMON-LISP"))
-
- (defun lisp-symbol? (string)
- ;; Good candidate for caching
- (multiple-value-bind (sym status)
- (find-symbol string lisp-package)
- (declare (ignore sym))
- (eq status :external)))
-
- (defun intern-renaming-perhaps (string package)
- (intern (if (or (eq package scheme-package)
- (not (lisp-symbol? string)))
- string
- (concatenate 'simple-string "." string))
- package))
-
- (defun find-symbol-renaming-perhaps (string package)
- (find-symbol (if (or (eq package scheme-package)
- (not (lisp-symbol? string)))
- string
- (concatenate 'simple-string "." string))
- package))
-